package com.sd365.permission.centre.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.sd365.common.core.annotation.stuffer.CommonFieldStuffer;
import com.sd365.common.core.annotation.stuffer.IdGenerator;
import com.sd365.common.core.annotation.stuffer.MethodTypeEnum;
import com.sd365.common.core.common.aop.MyPageInfo;
import com.sd365.common.core.common.exception.BusinessException;
import com.sd365.common.core.common.exception.code.BusinessErrorCode;
import com.sd365.common.core.context.BaseContextHolder;
import com.sd365.common.core.mq.ActionType;
import com.sd365.common.util.BeanException;
import com.sd365.common.util.BeanUtil;
import com.sd365.permission.centre.dao.mapper.TenantMapper;
import com.sd365.permission.centre.entity.Tenant;
import com.sd365.permission.centre.pojo.dto.DeleteTenantDTO;
import com.sd365.permission.centre.pojo.dto.TenantDTO;
import com.sd365.permission.centre.pojo.query.TenantQuery;
import com.sd365.permission.centre.service.TenantService;
import com.sd365.permission.centre.service.exception.UserCentreExceptionCode;
import com.sd365.permission.centre.service.util.SendMQMessageUtil;
import org.slf4j.Logger;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * @Auther: zhengkongjin
 * @Date: 2020/12/11/ 0011 22:06
 * @Description:
 */
@Service
public class TenantServiceImpl extends AbstractBaseDataServiceImpl implements TenantService {

    @Autowired
    TenantMapper tenantMapper;
    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private SendMQMessageUtil sendMQMessageUtil;

    /** 交换机名称  */
//    private static final String EXCHANGE_NAME = "directs";
    private static final String EXCHANGE_NAME = "centreToOmp_EXEC";
    /** 路由KEY  */
    private static final String ROUTE_KEY = "tenant";
    /** 数据表名  */
    private static final String TABLE_NAME = "basic_tenant";

    @CommonFieldStuffer(methodType = MethodTypeEnum.ADD)
    @Override
    public Boolean add(@Valid TenantDTO tenantDTO) {
        Tenant tenant= BeanUtil.copy(tenantDTO, Tenant.class);
        TenantDTO checkName = queryByName(tenant.getName());
        if(checkName != null){
            return false;
        }
        tenant.setId(idGenerator.snowflakeId());
        super.baseDataStuff4Add(tenant);
        if (tenantMapper.insert(tenant) > 0){
            sendMQMessageUtil.SendMessage(ActionType.INSERT,EXCHANGE_NAME,TABLE_NAME,tenant);
            return true;
        } else {
            return false;
        }
    }

    @CommonFieldStuffer(methodType = MethodTypeEnum.QUERY)
    @Override
    public List<TenantDTO> commonQuery(TenantQuery tenantQuery) {
        if(tenantQuery==null){
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("commonQuery 方法错误"));
        }
        try {
            // po list
            //List<Customer> customers= customerMapper.selectByExample(example);
            Tenant tenant = new Tenant();
            tenant.setName(tenantQuery.getName());
            tenant.setAccount(tenantQuery.getAccount());
            List<Tenant> tenants= tenantMapper.commonQuery(tenant);

            Page page = (Page) tenants;
            //将总数 页数拷贝到ThreadLocal
            BaseContextHolder.set("pageInfo", JSON.toJSONString(new MyPageInfo(page.getTotal(),page.getPages())));
            //对象转化 po list to dto list
            List<TenantDTO> tenantDTOS= BeanUtil.copyList(tenants, TenantDTO.class, new BeanUtil.CopyCallback() {
                @Override
                public void copy(Object o, Object o1) {
                    // 调用 BeanUtil.copyProperties
                    if(o==null || o1==null) {
                        throw new BeanException("拷贝对象不可以为空",new Exception("copyList 拷贝回调错误"));
                    }

                    Tenant tenantSource=(Tenant) o;
                    TenantDTO tenantDTO=(TenantDTO) o1;
                }
            });

            return tenantDTOS;
        } catch (BeanException ex){
            throw new BusinessException(BusinessErrorCode.SYSTEM_BEAN_COPY_EXCEPTION,ex);
        } catch (Exception ex){
            throw new BusinessException(UserCentreExceptionCode.BUSINESS_TMS_MONITOR_ORDER_STATISTICS_DB_EXCEPTION_CODE,ex);

        }
    }

    @CommonFieldStuffer(methodType = MethodTypeEnum.DELETE)
    @Override
    public Boolean remove(Long id, Long version) {
        try {
            Example example=new Example(Tenant.class);
            example.createCriteria().andEqualTo("id",id).andEqualTo("version",version);
            if(tenantMapper.deleteByExample(example)>0) {
                Tenant tenant = new Tenant();
                tenant.setId(id);
                tenant.setVersion(version);
                sendMQMessageUtil.SendMessage(ActionType.DELETE,EXCHANGE_NAME,TABLE_NAME,tenant);
                return true;
            }else {
                return false;
            }
        } catch (Exception ex){
            throw new BusinessException(UserCentreExceptionCode.BUSINESS_TMS_MONITOR_ORDER_STATISTICS_DB_EXCEPTION_CODE,ex);
        }
    }

    @CommonFieldStuffer(methodType = MethodTypeEnum.UPDATE)
    @Override
    public Boolean modify(TenantDTO tenantDTO) {
        try {
            Tenant tenant= BeanUtil.copy(tenantDTO, Tenant.class);

            Example example=new Example(Tenant.class);
            example.createCriteria().andEqualTo("id",tenantDTO.getId()).andEqualTo("version",tenantDTO.getVersion());
            super.baseDataStuff4Updated(tenant);
            if(tenantMapper.updateByExample(tenant,example)>0) {
                sendMQMessageUtil.SendMessage(ActionType.UPDATE,EXCHANGE_NAME,TABLE_NAME,tenant);
                return true;
            }else {
                return false;
            }
        }catch (BeanException ex){
            throw new BusinessException(BusinessErrorCode.SYSTEM_BEAN_COPY_EXCEPTION,ex);
        } catch (Exception ex){
            throw new BusinessException(UserCentreExceptionCode.BUSINESS_TMS_MONITOR_ORDER_STATISTICS_DB_EXCEPTION_CODE,ex);
        }
    }

    @CommonFieldStuffer(methodType = MethodTypeEnum.DELETE)
    @Override
    public Boolean batchDelete(DeleteTenantDTO[] deleteTenantDTOS) {
        Assert.notEmpty(deleteTenantDTOS,"批量删除参数不可以为空");
        List<Object> currentTenant = new ArrayList<>();
        for(DeleteTenantDTO deleteTenantDTO : deleteTenantDTOS){
            Example example=new Example(Tenant.class);
            example.createCriteria().andEqualTo("id",deleteTenantDTO.getId()).andEqualTo("version",deleteTenantDTO.getVersion()) ;
            int result=tenantMapper.deleteByExample(example);
            Assert.isTrue(result>0,String.format("删除的记录id %d 没有匹配到版本",deleteTenantDTO.getId()));
            currentTenant.add(deleteTenantDTO);
        }
        sendMQMessageUtil.SendMessage(ActionType.DELETE,EXCHANGE_NAME,TABLE_NAME,currentTenant);
        return true;
    }

    @CommonFieldStuffer(methodType = MethodTypeEnum.QUERY)
    @Override
    public TenantDTO queryById(Long id) {
        try{
            TenantDTO tenantDTO=null;
            Tenant tenant= tenantMapper.selectById(id);
            if(tenant!=null) {
                tenantDTO = BeanUtil.copy(tenant, TenantDTO.class);
            }
            return tenantDTO;
        }catch (BeanException ex){
            throw new BusinessException(BusinessErrorCode.SYSTEM_BEAN_COPY_EXCEPTION,ex);
        } catch (Exception ex){
            throw new BusinessException(UserCentreExceptionCode.BUSINESS_TMS_MONITOR_ORDER_STATISTICS_DB_EXCEPTION_CODE,ex);
        }
    }

    @CommonFieldStuffer(methodType = MethodTypeEnum.QUERY)
    @Override
    public TenantDTO queryByName(String name) {
        try{
            TenantDTO tenantDTO=null;
            Tenant tenant= tenantMapper.queryByName(name);
            if(tenant!=null) {
                tenantDTO = BeanUtil.copy(tenant, TenantDTO.class);
            }
            return tenantDTO;
        }catch (BeanException ex){
            throw new BusinessException(BusinessErrorCode.SYSTEM_BEAN_COPY_EXCEPTION,ex);
        } catch (Exception ex){
            throw new BusinessException(UserCentreExceptionCode.BUSINESS_TMS_MONITOR_ORDER_STATISTICS_DB_EXCEPTION_CODE,ex);
        }
    }
}
